/**
 * @(#)StringUtil.java Jan 2, 2008
 *
 * Copyright (c) 2005-2010 Psiqueware S.A. de C.V. All Rights Reserved.
 * This software is the proprietary information Psiqueware S.A. de C.V.
 * Use is subject to license terms.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * <br/>Usuario : AngelElectrico
 * <br/>Creaci&oacute;n: Jan 2, 2008 - 4:07:21 PM
 * <br/>
 * <br/>
 * <br/><t5>Cambios :</t5>
 * <br/><b>Fecha | Autor  |  Cambios</b>
 * <ul>
 * <li>Jan 2, 2008 | <a href = "mailto:AngelElectrico@PsiqueWare.com">Angel El&eacute;ctrico</a> | Creaci&oacute;n del Objeto.</li>
 *
 * </ul>
 */

package com.psiqueware.alheli.basico.util;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.regex.Pattern;


/**
 * Conjunto de utilidades para el tratamiento de cadenas.
 * <br/>Paquete Original: com.psiqueware.basico.gui.dibujable.componentes.texto.panel.util
 * <br/>Nombre  Original: StringUtil
 * <br/>Oprima para ver : <a href="StringUtil.java.html"><i>C&oacute;digo Fuente</i> </a>
 *
 * @author <a href="mailto:AngelElectrico@PsiqueWare.com">Angel El&eacute;ctrico</a>
 * @version Revision: 1.1 Jan 2, 2008 4:07:21 PM
 * @noinspection UnusedDeclaration
 */
public final class StringUtil
{


    /**
     * Constructor de StringUtil.
     */
    public StringUtil()
    {

    }

    /**
     * Limpia los caracteres especiales de una cadena.
     *
     * @param original cadena original.
     *
     * @return la cadena despues de ser procesada.
     */
    public static String limpiaCaracteresSpeciales(final String original)
    {
        char[] anteriores = original.toCharArray();
        char[] nuevos = new char[anteriores.length];
        for (int j = 0; j < anteriores.length; j++)
        {
            final char anterior = anteriores[j];
            Character.UnicodeBlock ub = Character.UnicodeBlock.of(anterior);
            if (ub == null || !ub.equals(Character.UnicodeBlock.BASIC_LATIN))
            {
                nuevos[j] = '_';
            }
            else if (!Character.isLetter(anterior) && !Character.isDigit(anterior))
            {
                nuevos[j] = '-';
            }
            else
            {
                nuevos[j] = anteriores[j];
            }
        }
        return new String(nuevos);
    }

    /**
     * Divide una cadena a partir de un delimitador.
     *
     * @param texto       a dividir en secciones.
     * @param delimitador que se buscar&aacute; para realizar las divisiones.
     *
     * @return un arreglo de Strings, nunca nulo.
     *
     * @noinspection unchecked
     */
    public static String[] split(String texto, String delimitador)
    {
        if (null == texto) throw new IllegalArgumentException("<error>El argumento 'texto' no puede ser NULL.</error>");
        if (null == delimitador)
            throw new IllegalArgumentException("<error>El argumento 'delimitador' no puede ser NULL.</error>");

        Vector vector = new Vector();
        StringTokenizer st = new StringTokenizer(texto, delimitador);
        while (st.hasMoreTokens())
            vector.addElement(st.nextToken());
        String[] sa = new String[vector.size()];
        vector.copyInto(sa);
        return sa;
    }

    /**
     * Ordena las cadenas del arreglo alfab&eacute;ticamente. Utiliza el algoritmo de la burbuja.
     *
     * @param arreglo a ordenar.
     *
     * @return arreglo con las cadenas ordenadas.
     *
     * @noinspection unchecked
     */
    public static String[] ordenadorBurbuja(String[] arreglo)
    {
        if (null == arreglo)
            throw new IllegalArgumentException("<error>El argumento 'arreglo' no puede ser NULL.</error>");

        final int totalElementos = arreglo.length;
        final Vector elementos = new Vector(totalElementos);

        for (int i = 0; i < (totalElementos - 1); i++)
        {
            if (((String) elementos.elementAt(i)).compareTo(
                    ((String) elementos.elementAt(i + 1))) > 0)
            {
                String tmp = (String) elementos.elementAt(i + 1);
                elementos.removeElementAt(i + 1);
                elementos.insertElementAt(tmp, i);
            }
        }

        String[] out = new String[totalElementos];

        elementos.copyInto(out);
        return out;
    }


    public static String maxCommonPrefix(String one, String two)
    {
        int i = 0;
        while (one.regionMatches(0, two, 0, i))
            i++;
        return one.substring(0, i - 1);
    }


    /**
     * Divide un nombre de archivo en archivo y directorio.
     *
     * @param nombreCalificadoArchivo nombre del archivo a dividir.
     *
     * @return String [] { directorio, nombreCalificadoArchivo }
     */
    public String[] divideNombreArchivo(String nombreCalificadoArchivo)
    {
        if (null == nombreCalificadoArchivo)
            throw new IllegalArgumentException("<error>El argumento 'nombreCalificadoArchivo' no puede ser NULL.</error>");
        if (0 == nombreCalificadoArchivo.trim().length())
            throw new IllegalArgumentException("<error>El argumento 'nombreCalificadoArchivo' es una cadena vacia.</error>");

        String directorio, nombre;
        int i = nombreCalificadoArchivo.lastIndexOf(File.separator);
        if (i != -1)
        {
            directorio = nombreCalificadoArchivo.substring(0, i);
            nombre = nombreCalificadoArchivo.substring(i + 1);
        }
        else
        {
            nombre = nombreCalificadoArchivo;
            directorio = "";
        }
        return new String[]{directorio, nombre};
    }

    /**
     * Mapa de entidades para ser sustituidas.
     */
    private static Map<String, String> entidades = new HashMap<String, String>();

    private static Pattern SPACE_PATTERN = Pattern.compile(" ");

    /**
     * Sustituye algunas de las entidades de Formato mas b&aacute;sicas
     * del espa&ntilde;ol por sus versiones en texto Unicode.
     *
     * @param cadena con entidades Formato adscritas.
     *
     * @return la cadena con las entidades susituidas.
     */
    public static String sustituyeEntidadesHTML(final String cadena)
    {
        if (entidades.isEmpty())
        {
            final ResourceBundle rb = ResourceBundle.getBundle(StringUtil.class.getName());
            for (final String value : entidades.values())
            {
                final String[] valores = SPACE_PATTERN.split(value);
                entidades.put(valores[0], valores[1]);
            }
        }

        String salida = cadena;
        for (final Map.Entry<String, String> entry : entidades.entrySet())
        {
            salida = salida.replace(entry.getKey(), entry.getValue());
        }
        return salida;
    }

}

